package com.kalua.list.domainmodel.retailer;

import java.time.Instant;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.kalua.list.domainmodel.MutablePersistentEntity;
import com.kalua.list.domainmodel.NumericId;
import com.kalua.list.domainmodel.TextIdentifier;

public class CrawlBatchInfoImpl implements 	CrawlBatchInfo, 
																		MutablePersistentEntity<NumericId> {

	private static final long serialVersionUID = 4376368997442785379L;
		
	
	private NumericId id;
	private NumericId previousBatchId;	
	private TextIdentifier retailerId;
	private Instant timeStarted;		
	private Instant timeCompleted;
	private int numberOfProductsExtracted;

	@JsonIgnore
	private AtomicInteger updateCount;
	@JsonIgnore
	private AtomicInteger createCount;
	@JsonIgnore
	private AtomicInteger internalFailureCount;	
	@JsonIgnore
	private AtomicInteger nonViableCount;

	private CrawlBatchInfoImpl() { 
		setNumberOfProductsExtracted(0); 
		this.updateCount = new AtomicInteger(0);
		this.createCount = new AtomicInteger(0);
		this.internalFailureCount = new AtomicInteger(0);
		this.nonViableCount = new AtomicInteger(0);
	}
	
	public CrawlBatchInfoImpl(	NumericId id,
												NumericId previousBatchId,
												TextIdentifier retailerId,
												Instant timeStarted) {
		this();
		setId(id);
		setPreviousBatchId(previousBatchId);
		setRetailerId(retailerId);
		setTimeStarted(timeStarted);
	}
	
	public CrawlBatchInfoImpl(	NumericId previousBatchId, 
												TextIdentifier retailerId,
												Instant timeStarted) {
		this(null, previousBatchId, retailerId, timeStarted);
	}	
	
	@Override
	public NumericId getId() { return this.id; }
	@Override
	public void setId(NumericId id) { this.id = id; }
	
	@Override
	public NumericId getPreviousBatchId() { return this.previousBatchId; }
	public void setPreviousBatchId(NumericId previousBatchId) 
	{this.previousBatchId = previousBatchId; }
	
	@Override
	public TextIdentifier getRetailerId() { return this.retailerId; }
	public void setRetailerId(TextIdentifier retailerId) 
	{ this.retailerId = retailerId; }
	
	@Override
	public Instant getTimeStarted() { return this.timeStarted; }
	public void setTimeStarted(Instant timeStarted) { this.timeStarted = timeStarted; }
	
	@Override
	public Instant getTimeCompleted() { return this.timeCompleted; }
	public void setTimeCompleted(Instant timeCompleted) { this.timeCompleted = timeCompleted; }
	
	@Override
	public int getNumberOfProductsExtracted()  { return this.numberOfProductsExtracted; }
	public void setNumberOfProductsExtracted(int numberOfProductsExtracted) 
	{ this.numberOfProductsExtracted = numberOfProductsExtracted; }


	public String toStringLong() {
		return "CrawlBatchInfoImpl [id=" + id
					+ ", previousBatchId=" + previousBatchId + ", retailerId="
					+ retailerId + ", numberOfProductsExtracted="
					+ numberOfProductsExtracted + ", timeStarted=" + timeStarted
					+ ", timeCompleted=" + timeCompleted + "]";
	}

	@Override
	public String toString() 
	{ return "CrawlBatchInfo [" + id+ " - (" + numberOfProductsExtracted + ")]"; }

	@Override
	public int getUpdateCount() { return this.updateCount.get();}
	public void setUpdateCount(int value) {this.updateCount.set(value); }
	
	@Override
	public void incrementUpdateCount() { this.updateCount.incrementAndGet(); }

	@Override
	public int getCreateCount() { return this.createCount.get(); }
	public void setCreateCount(int value) { this.createCount.set(value); }
	@Override
	public void incrementCreateCount()  { this.createCount.incrementAndGet(); }

	@Override
	public int getInternalFailureCount()  { return this.internalFailureCount.get(); }
	public void setInternalFailureCount(int value) { this.internalFailureCount.set(value); }	
	@Override
	public void incrementInternalFailureCount()  { this.internalFailureCount.incrementAndGet();}
	
	@Override
	public int getNonViableCount() {return this.nonViableCount.get(); }
	public void setNonViableCount(int value) { this.nonViableCount.set(value); }	
	@Override
	public void incrementNonViableCount() 
	{ this.nonViableCount.incrementAndGet();  }
	
	
	@Override
	public int hashCode() {	 return this.id.hashCode(); }
	
	@Override
	public boolean equals(Object obj) {
		boolean result;
		if (this == obj)
			result = true;
		else if (obj !=null && obj instanceof CrawlBatchInfoImpl) {
			CrawlBatchInfoImpl other = (CrawlBatchInfoImpl)obj;
			Object[] fields = 
					new Object[]{	this.id, this.previousBatchId, 
											this.retailerId, this.timeStarted, 
											this.timeCompleted, this.numberOfProductsExtracted,
											this.getInternalFailureCount(), this.getCreateCount(),
											this.getUpdateCount(), this.getNonViableCount()};			
			Object[] otherFields = 
					new Object[]{	other.id, other.previousBatchId, 
											other.retailerId, other.timeStarted, 
											other.timeCompleted, other.numberOfProductsExtracted,
											other.getInternalFailureCount(), other.getCreateCount(),
											other.getUpdateCount(), other.getNonViableCount()};			
			result = Arrays.equals(fields, otherFields);			
		} else result = false;		
		return result;
	}	
}